Skip to content

Web Serving ​

Serve dynamic web content directly from AO processes using HyperBEAM. This guide shows how to host websites, serve HTML/CSS/JavaScript, and update content in real-time using an experimental Hyper AOS light implementation.

Prerequisites ​

  • HyperBeam server running locally
    • rebar3 shell from your local HyperBeam repo
  • Experimental Hyper AOS light module

Setting Up the Environment ​

First, export the AOS module and install the latest preview version of the AOS console:

bash
# Install the latest preview version of AOS console
preview_ao.arweave.net

This installation enables the Lua device on HyperBeam to function as your process's virtual machine.

Creating a Process ​

To create a new process on your HyperBeam server:

  1. Spin up a new process using the AOS module as the initialization script
    • export AOS_MODULE=<HyperAOS-Module-ID>
  2. Select the Lua device in the configuration options
  3. Verify the process is running with the experimental Hyper AOS

File Structure ​

For this demonstration, we'll use three main files:

  • app.css.lua - CSS styling wrapped in a Lua file
  • app.js.lua - JavaScript functionality wrapped in a Lua file
  • now.html.lua - HTML content wrapped in a Lua file

State Management ​

Unlike Genesis WASM which requires sending messages to cache with the patch device, Hyper AOS makes state directly available:

lua
-- Access state
State["someProperty"]
-- Modify state
State["someProperty"] = newValue

Loading Web Assets ​

CSS File ​

Load the CSS file into the process state:

lua
.load app.css.lua

The CSS file sets the content type and body:

lua
State["app.css"] = {
  ["content-type"] = "text/css",
  body = [[
        /* CSS styles */
        * {
          margin: 0;
          padding: 0;
          box-sizing: border-box;
        }

        body {
          font-family: Arial, sans-serif;
          background: linear-gradient(180deg, #87CEEB 0%, #9980C8 100%);
          min-height: 100vh;
          overflow-x: hidden;
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
        }

        h1 {
          color: #333;
          margin-bottom: 2rem;
          text-align: center;
          font-size: 2.5rem;
          text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
        }

        .marquee-container {
          width: 100%;
          height: 200px;
          background: rgba(255, 255, 255, 0.3);
          backdrop-filter: blur(10px);
          position: relative;
          overflow: hidden;
          box-shadow: 0 4px 6px rgba(0,0,0,0.1);
        }

        .marquee-track {
          display: flex;
          position: absolute;
          animation: scroll 20s linear infinite;
          height: 100%;
          align-items: center;
        }
    ]]
}

JavaScript File ​

Similarly, load the JavaScript file:

lua
.load app.js.lua

The JavaScript file follows the same pattern:

lua
State["app.js"] = {
  ["content-type"] = "application/javascript",
  body = [[ // JavaScript content here ]]
}

HTML File ​

Finally, load the HTML file:

lua
.load now.html.lua

The HTML file is placed at the root of the state:

lua
State["content-type"] = "text/html"
State["body"] = [[
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>HyperBeam Marquee Demo</title>
        <link rel="stylesheet" type="text/css" href="now/app.css" />
    </head>
    <body>
        <div class="cloud cloud1"></div>
        <div class="cloud cloud2"></div>

        <h1>Elephant Parade</h1>

        <div class="marquee-container">
            <div class="marquee-track" id="marqueeTrack">
                <!-- Elephants will be added here by JavaScript -->
            </div>
        </div>
        <div class="ground"></div>

        <script type="text/javascript" src="now/app.js"></script>
    </body>
    </html>
]]

Note that the HTML references other assets using the path now/app.css and now/app.js.

Accessing Your Web Application ​

  1. Retrieve your process ID by examining the inbox commitments:
lua
Inbox[1].commitments
  • Look for the signed ID (RSAPS-SHA-256). This appears as a long alphanumeric string like 6oNYypU3EIeauMkTL4EEYKgzASYFebqTCLP8W1idmMB.
  1. Access your web application in a browser:
localhost:8734/<processID>~process@1.0/now
  • Replace the process ID with your actual process ID from the commitments

Making Dynamic Updates ​

To demonstrate the dynamic nature of this approach:

  1. Modify your HTML file (e.g., change a heading to "Elephant Parade on the beam")
  2. Save the changes
  3. Reload the file in the AOS console:
lua
.load now.html.lua
  1. Refresh your browser to see the changes

Advanced Capabilities ​

This approach allows for:

  • Real-time updates to web content
  • Processing incoming messages to modify the website
  • Adding additional content dynamically
  • Creating interactive web applications directly within HyperBeam processes

Warning ​

The Hyper AOS light implementation used in this guide is experimental and should not be used for production environments. It is intended for demonstration purposes only.